#include"../../include/cooker.h"

#define TRUE  1
#define FALSE 0

using namespace std;

void GetGateWay(char gateway[])  
{  
    FILE *fp;  
    char buf[512];  
    char cmd[128]; 
    char *tmp;  

    strcpy(cmd, "ip route");  
    fp = popen(cmd, "r"); 
    if(NULL == fp)  
    {  
	perror("popen error");  
	return ;  
    }  
    while(fgets(buf, sizeof(buf), fp) != NULL)  
    {  
	tmp =buf;  
	while(*tmp && isspace(*tmp))  
	    ++ tmp;  
	if(strncmp(tmp, "default", strlen("default")) == 0)  
	    break;  
    }  
    sscanf(buf, "%*s%*s%s", gateway);         
    printf("本地网关:%s\n", gateway);  
    pclose(fp);  
}  



void Get_IP_addr (char ip_address[])
{
    struct ifaddrs * ifAddrStruct=NULL;
    void * tmpAddrPtr=NULL;

    char gateway[30];  
    getifaddrs(&ifAddrStruct);

 
    GetGateWay(gateway);
    
    while (ifAddrStruct!=NULL) 
    {
	if (ifAddrStruct->ifa_addr->sa_family==AF_INET)
	{   // check it is IP4
	    // is a valid IP4 Address
	    tmpAddrPtr=&((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
	    char addressBuffer[INET_ADDRSTRLEN];
	    inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
	    if(0==strncmp(gateway,addressBuffer,12))
	    {
		printf("网卡标识:%s\n本地IP地址:%s\n", ifAddrStruct->ifa_name, addressBuffer); 
		strcpy(ip_address,addressBuffer);
		break;
	    }
	}
	ifAddrStruct=ifAddrStruct->ifa_next;
    }

//    return 0;
}

CookerClient::CookerClient(){
    Msg.client=CurrentClient;
    OrderList = NULL;
    ChangeList= NULL;
}

CookerClient::~CookerClient(){
    delete OrderList;
    delete ChangeList;
}



void CookerClient::ConnetServer(){
	//************TCP连接*****************//
	int ret;
	//建立套接字，确定要使用的协议家族
	socket_fd = socket(AF_INET,SOCK_STREAM,0);
	if(socket_fd == -1){
	    perror("socket");
	    return ;
	}

	//绑定地址和端口
	ServerSin.sin_family = AF_INET;
	ServerSin.sin_port = htons(ServerPort);
	//ip地址是服务器ip地址
	if(inet_pton(AF_INET,ServerLocalHost,&ServerSin.sin_addr.s_addr) <=0){
	    perror("inet_pton");
	    return ;
	}
	ret = connect(socket_fd,(struct sockaddr*)&ServerSin,sizeof(ServerSin));
	if(ret == -1){
	    perror("连接服务器失败");
	    return ;
	}else{
	    printf("成功连接服务器!\n");
	}

	//*************TCP连接结束*********************//
}

void CookerClient::SendMessage(){
    Msg.client= CurrentClient;
    Msg.ContentSum=0;
    char buf[1024]={0};

    Content tmp;
    if(Msg.ConnetType==ConnetNewFood){
	FoodList *p=ChangeList;
	char buf1[MaxPackSize-HeaderSize];
	while(p!=NULL){
	    ushort pos=Msg.ContentSum*ContentSize;
	    ++Msg.ContentSum;
	    tmp.FoodNum=p->FoodNum;
	    tmp.FoodSum=p->FoodSum;
	    strcpy(tmp.Remark,p->Remark);
	    memcpy(&buf1[pos],&tmp,ContentSize);
	    p=p->next;
	    if((Msg.ContentSum>=MaxContentSum)&&(p!=NULL)){
		Msg.PackIsEnd =NoEnd;
		memcpy(buf,&Msg,HeaderSize);
		memcpy(&buf[HeaderSize],buf1,MaxPackSize-HeaderSize);
		write(socket_fd,buf,1024);
		Msg.ContentSum=0;
		memset(buf1,0,MaxPackSize-HeaderSize);
	    }
	}
	Msg.PackIsEnd =IsEnd;
	memcpy(buf,&Msg,HeaderSize);
	memcpy(&buf[HeaderSize],buf1,MaxPackSize-HeaderSize);
	write(socket_fd,buf,1024);
	delete ChangeList;
    }else if(Msg.ConnetType==ConnetOldFood||Msg.ConnetType==ConnetUpOldFood){
	FoodList *p=OrderList;
	char buf1[RWMaxSize-HeaderSize];
	while(p!=NULL){
	    ushort pos=Msg.ContentSum*ContentSize;
	    ++Msg.ContentSum;
	    tmp.FoodNum=p->FoodNum;
	    tmp.FoodSum=p->FoodSum;
	    strcpy(tmp.Remark,p->Remark);
	    memcpy(&buf1[pos],&tmp,ContentSize);
	    p=p->next;
	    if((Msg.ContentSum>=MaxContentSum)&&(p!=NULL)){
		Msg.PackIsEnd =NoEnd;
		memcpy(buf,&Msg,HeaderSize);
		memcpy(buf,buf1,MaxPackSize-HeaderSize);
		write(socket_fd,buf,1024);
		Msg.ContentSum=0;
		memset(buf1,0,MaxPackSize-HeaderSize);
	    }
	}
	Msg.PackIsEnd =IsEnd;
	memcpy(buf,&Msg,HeaderSize);
	memcpy(&buf[HeaderSize],buf1,MaxPackSize-HeaderSize);
	write(socket_fd,buf,1024);
	
    }else{
	Msg.PackIsEnd =IsEnd;
	memcpy(buf,&Msg,HeaderSize);
	write(socket_fd,buf,1024);
    }
}

void CookerClient::ReceiveMessage(){
    char buf[RWMaxSize];
    read(socket_fd,buf,RWMaxSize);
    memcpy(&Msg,buf,HeaderSize);
    Content tmp={0,0,0};	
    if(Msg.ConnetType==ConnetOkFood){	
	int ContentSum=0;
	map<ushort,string>TmpResult;//桌号-称呼
	ResultTable=TmpResult;
	while(Msg.ContentSum--){
	    memcpy(&tmp,&buf[HeaderSize+ContentSize*ContentSum],ContentSize);
	    ++ContentSum;
	    ResultTable[tmp.FoodNum]=tmp.Remark;
	}
    }else if(Msg.ConnetType==ConnetGetUsedTable){	
	int ContentSum=0;
	map<ushort,map<string,ushort>> TmpTable;//桌号-桌名-状态
	AllTable=TmpTable;
	while(Msg.ContentSum--){
	    memcpy(&tmp,&buf[HeaderSize+ContentSize*ContentSum],ContentSize);
	    ++ContentSum;
	    map<string,ushort>maptmp;
	    maptmp[tmp.Remark]=tmp.FoodSum;
	    AllTable[tmp.FoodNum]=maptmp;
	}
    }else if(Msg.ConnetType==ConnetGetFood||Msg.ConnetType==ConnetGetDownFood){	
	int ContentSum=0;
	map<ushort,map<ushort,string>> TmpFood;//菜编号-价格-备注
	AllFood=TmpFood;
	while(Msg.ContentSum--){
	    memcpy(&tmp,&buf[HeaderSize+ContentSize*ContentSum],ContentSize);
	    ++ContentSum;
	    map<ushort,string>maptmp;
	    maptmp[tmp.FoodSum]=tmp.Remark;
	    AllFood[tmp.FoodNum]=maptmp;
	}
    }else if(Msg.ConnetType==ConnetGetOrderFood){	
	int ContentSum=0;
	FoodList *TmpList=new FoodList;
	TmpList->next=NULL;
	OrderList=TmpList;
	while(Msg.ContentSum--){
	    memcpy(&tmp,&buf[HeaderSize+ContentSize*ContentSum],ContentSize);
	    ++ContentSum;
	    FoodList *newTL=new FoodList;
	    newTL->next=NULL;
	    newTL->FoodNum=tmp.FoodNum;
	    newTL->FoodSum=tmp.FoodSum;
	    strcpy(newTL->Remark,tmp.Remark);
	    OrderList->next=newTL;
	    newTL->pre=OrderList;
	    OrderList=OrderList->next;
	}
	OrderList=TmpList->next;
    }else{	
    }
}


void CookerClient::MainMenu(){
    cout<<"----------------------------------"<<endl;
    cout<<"1.上架菜类"<<endl;
    cout<<"2.下架菜类"<<endl;
    cout<<"3.上菜服务"<<endl;
    cout<<"4.餐桌信息"<<endl;
    cout<<"5.已下架菜单"<<endl;
    cout<<"----------------------------------"<<endl;
    cout<<">>";
    string Chose;
    cin>>Chose;
    while(Chose==""||Chose<"1"||Chose>"5"){
	cout<<"选择错误，重新选择"<<endl;
	cout<<">>";
	cin>>Chose;
    }
    if(Chose=="1"){
	UpFood();
    }else if(Chose=="2"){
	DownFood();
    }else if(Chose=="3"){
	OkFood();
    }else if(Chose=="4"){
	OrderInfo();
    }else if(Chose=="5"){
	DownInfo();
    }else{
	MainMenu();
    }

}


void CookerClient::OrderInfo(){
    Msg.ConnetType=ConnetGetUsedTable;
    SendMessage();
    ReceiveMessage();
    ShowAllTable();
    Msg.ConnetType=ConnetGetFood;
    SendMessage();
    ReceiveMessage();
    cout<<"菜单详情"<<endl;
    for(auto it=AllTable.begin();it!=AllTable.end();it++){
	auto ii=it->second.begin()->second;
	if(ii!=0){
	    cout<<"桌号："<<it->first<<endl;
		Msg.ConnetType=ConnetGetOrderFood;
	   Msg.TableNum=it->first;
	   SendMessage();
	   ReceiveMessage();
	   ShowOrderList();

	}
    }
    MainMenu();
}



void CookerClient::OkFood(){
    Msg.ConnetType=ConnetGetUsedTable;
    SendMessage();
    ReceiveMessage();
    string Chose;
    ushort EnterNum;
    while(1){
	cout<<"房间列表"<<endl;
	ShowAllTable();
	cout<<"选择房间"<<endl;
	cout<<">>";
	cin>>Chose;
	EnterNum=atoi(Chose.c_str());
	if(AllTable.end()==AllTable.find(EnterNum)){
	    cout<<"没有这个房间哦，重新选择吧"<<endl;
	    continue;
	}else{
	    Msg.ConnetType=ConnetOkFood;
	    Msg.TableNum=EnterNum;
	    SendMessage();
	    ReceiveMessage();
	    break;
	}
    }
    MainMenu();


}


void CookerClient::DownInfo(){
    Msg.ConnetType=ConnetGetDownFood;
    SendMessage();
    ReceiveMessage();
    string Chose;
    ushort EnterNum;
    while(1){
	cout<<"----------------------------"<<endl;
	cout<<"下架菜单如下"<<endl;
	ShowAllFood();
	if(AllFood.empty()){
	    cout<<"菜单为空"<<endl;
	    break;
	}
	cout<<"----------------------------"<<endl;
	cout<<"恢复上架菜单如下"<<endl;
	ShowOrderList();
	cout<<"输入菜编号(输入ok完成)"<<endl;
	cout<<">>";
	cin>>Chose;
	FoodList *p=OrderList;
	if(Chose=="ok"||Chose=="OK"){
	    if(p){
		Msg.ConnetType=ConnetUpOldFood;
		SendMessage();
		ReceiveMessage();
	    }else{
		cout<<"本次未恢复上架任何菜"<<endl;
	    }
	    break;
	}
	EnterNum=atoi(Chose.c_str());
	if(AllFood.end()==AllFood.find(EnterNum)){
	    cout<<"没有这个菜哦，重新选择吧"<<endl;
	    continue;
	}
	if(!p){
	    OrderList=new FoodList;
	    OrderList->next=NULL;
	    cout<<"OrderList==NULL"<<endl;
	    p=OrderList;
	    p->FoodNum=EnterNum;
	    p->FoodSum=1;
	}else{
	    while(p){
		if(p->FoodNum==EnterNum)
		    break;
		p=p->next;
	    }
	    if(p==NULL){
		p=OrderList;
		while(p->next){
		    p=p->next;
		}
		FoodList *tmp=new FoodList;
		tmp->next=NULL;
		tmp->FoodNum=EnterNum;
		tmp->FoodSum=1;
		p->next=tmp;
		tmp->pre=p;
	    }
	}
    }
    if(OrderList!=NULL)
    OrderList->next=NULL;
    OrderList=NULL;
    MainMenu();

}




void CookerClient::DownFood(){
    Msg.ConnetType=ConnetGetFood;
    SendMessage();
    ReceiveMessage();
    if(OrderList!=NULL)
    OrderList->next=NULL;
    OrderList=NULL;

    string Chose;
    ushort EnterNum;
    while(1){
	ShowAllFood();
	cout<<"----------------------------"<<endl;
	cout<<"下架菜单如下"<<endl;
	ShowOrderList();
	cout<<"输入菜编号(输入ok完成)"<<endl;
	cout<<">>";
	cin>>Chose;
	FoodList *p=OrderList;
	if(Chose=="ok"||Chose=="OK"){
	    if(p){
		Msg.ConnetType=ConnetOldFood;
		SendMessage();
		ReceiveMessage();
	    }else{
		cout<<"本次未下架任何菜"<<endl;
	    }
	    break;
	}
	EnterNum=atoi(Chose.c_str());
	if(AllFood.end()==AllFood.find(EnterNum)){
	    cout<<"没有这个菜哦，重新选择吧"<<endl;
	    continue;
	}
	if(!p){
	    OrderList=new FoodList;
	    OrderList->next=NULL;
	    p=OrderList;
	    p->FoodNum=EnterNum;
	    auto it=(AllFood.find(EnterNum))->second.begin()->second;
	    strcpy(p->Remark,it.c_str());
	    p->FoodSum=1;
	}else{
	    while(p){
		if(p->FoodNum==EnterNum)
		    break;
		p=p->next;
	    }
	    if(p==NULL){
		p=OrderList;
		while(p->next){
		    p=p->next;

		}
		FoodList *tmp=new FoodList;
		tmp->next=NULL;
		tmp->FoodNum=EnterNum;
		auto it=(AllFood.find(EnterNum))->second.begin()->second;
		strcpy(tmp->Remark,it.c_str());
		tmp->FoodSum=1;
		p->next=tmp;
		tmp->pre=p;
	    }
	}
    }
    if(OrderList!=NULL)
    OrderList->next=NULL;
    OrderList=NULL;
    MainMenu();
}

void CookerClient::UpFood(){
    string Chose;
    ushort EnterNum;
    Msg.ConnetType=ConnetNewFood;
    ChangeList=NULL;
    while(1){
	cout<<"新上架菜单如下"<<endl;
	cout<<"-----------------------------"<<endl;
	ShowChangeList();
	cout<<"-----------------------------"<<endl;
	cout<<"输入菜名：";

	cin>>Chose;
	if(Chose=="ok"||Chose=="OK"){
	    break;
	}
	if(ChangeList==NULL){
	    ChangeList=new FoodList;
	    ChangeList->next=NULL;
	}
	FoodList *p=ChangeList;

	while(p){
	    if(0==strcmp(Chose.c_str(),p->Remark))
		break;
	    p=p->next;
	}
	if(p!=NULL){
	    cout<<"重名了，重新输入"<<endl;
	    continue;
	}
	p=ChangeList;

	while(p->next!=NULL){
	    p=p->next;
	}
	



	FoodList *tmp=new FoodList;
	tmp->next=NULL;
	strcpy(tmp->Remark,Chose.c_str());
	cout<<"输入价格：";
	cin>>EnterNum;
	tmp->FoodSum=EnterNum;
	tmp->FoodNum=0;
	p->next=tmp;
	tmp->pre=p;
	cout<<"继续添加？(y/n)";
	cout<<">>";
	cin>>Chose;
	if(Chose=="y"||Chose=="Y"){
	    continue;
	}else{
	    ChangeList=ChangeList->next;
	    SendMessage();
	    ReceiveMessage();
	    break;
	}
    }
    if(ChangeList!=NULL)
    ChangeList->next=NULL;
    ChangeList=NULL;
    MainMenu();
}






void CookerClient::ShowAllFood(){
    cout<<"本店菜单"<<endl;
    if(AllFood.empty())return;
    for(auto it=AllFood.begin();it!=AllFood.end();it++){
	auto ii=it->second.begin();
	cout<<"编号："<<it->first<<" "<<ii->second<<" ￥"<<ii->first<<endl;
    }
}
void CookerClient::ShowResultTable(){
    if(ResultTable.empty())return;
    for(auto it=ResultTable.begin();it!=ResultTable.end();it++){
   cout<<"房间："<<it->first<<" "<<it->second<<endl;
    }

}

void CookerClient::ShowOrderList(){
    FoodList *p=OrderList;
    while(p){
	cout<<p->FoodNum<<" "<<(AllFood.find(p->FoodNum)->second).begin()->second<<" 份数："<<p->FoodSum<<endl;
	p=p->next;
    }
}

void CookerClient::ShowChangeList(){
    FoodList *p =ChangeList;
    if(p){
	p=p->next;
    }
    while(p){
	cout<<p->FoodNum<<" "<<p->Remark<<" 份数："<<p->FoodSum<<endl;
	p=p->next;
    }
}
void CookerClient::ShowAllTable(){
    cout<<"所有餐台列表"<<endl;
    if(!AllTable.empty()){
	for(auto it=AllTable.begin();it!=AllTable.end();it++){

	    cout<<"桌号："<<it->first<<" ";
	    cout<<"桌名："<<((it->second).begin())->first<<" ";
	    cout<<"状态：";
	    switch((it->second).begin()->second){
		case 0:cout<<"空闲"<<endl;break;
		case 1:cout<<"服务中"<<endl;break;
		case 2:cout<<"呼叫服务员"<<endl;break;
		case 3:cout<<"待结帐"<<endl;break;
		case 4:cout<<"待上菜"<<endl;break;
		case 5:cout<<"待换房"<<endl;break;
		default:cout<<"未知"<<endl;
	    }
	}
    }
}



int main()
{
    CookerClient cooker;
    cooker.ConnetServer();
    cooker.MainMenu();
    return 0;
}
